/*
    测试非阻塞IO
*/
#include <iostream>
#include <unistd.h>
#include <fcntl.h>

void setNoBlock(int fd) // 设置文件描述符状态为非阻塞
{
    int flag = fcntl(fd, F_GETFL); // 获取文件描述符的状态
    if (flag < 0)
    {
        perror("fcntl");
        return;
    }
    fcntl(fd, F_SETFL, flag | O_NONBLOCK); // 添加非阻塞标志
}

void test1()
{
    /*
        测试文件描述符fd=0(标准输入流)，如果缓冲区没有数据就一直阻塞，等待缓冲区中有数据才读
    */
    char buf[1024] = {0};
    read(0, buf, sizeof(buf)); // 从标准输入中读取
    std::cout << buf;
}

void test2()
{
    /*
        测试文件描述符fd=0(标准输入流)，如果缓冲区没有数据就直接返回
    */
    setNoBlock(0); // 将标准输入设置为非阻塞
    char buf[1024] = {0};
    while (true)
    {
        int ret = read(0, buf, sizeof(buf)); // 从标准输入中读取
        std::cout << "ret:" << ret << std::endl;
        if (ret > 0)
        {
            std::cout << buf << std::endl;
        }
        else if (ret == 0)
        {
            std::cout << "对端链接关闭\n";
        }
        else
        {
            // <0: 1、要么底层事件没有就绪 2、要么读取错误
            // 需要进一步根据errno判断具体是哪种情况
            if (errno == EWOULDBLOCK || errno == EAGAIN)
            {
                std::cout << "事件没有就绪\n";
            }
            else if (errno == EINTR) // 读取的时候，可能遇到了信号要求处理，被中断了，此时下次应该继续读
            {
                std::cout << "接着读\n";
                continue;
            }
            else
            {
                std::cout << "读取错误\n";
            }
        }
        sleep(1);
    }
}

int main()
{
    // test1();
    test2();
    return 0;
}